import fetch from 'dva/fetch';
import { notification } from 'antd';

const codeMessage = {
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};

const checkStatus = response => {
  if (response.status >= 403) {
    const error = new Error();
    error.response = response;
    error.status = response.status;
    throw error;
  } else {
    return response;
  }
};

/**
 * Requests a URL, returning a promise.
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [option] The options we want to pass to "fetch"
 * @return {object}           An object containing either "data" or "err"
 */
export default function request(url, option) {
  const newOptions = { ...option };

  if (
    newOptions.method === 'POST' ||
    newOptions.method === 'PUT' ||
    newOptions.method === 'DELETE'
  ) {
    if (!(newOptions.body instanceof FormData)) {
      newOptions.headers = {
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8',
        ...newOptions.headers,
      };
      newOptions.body = JSON.stringify(newOptions.body);
    } else {
      // newOptions.body is FormData
      newOptions.headers = {
        Accept: 'application/json',
        ...newOptions.headers,
      };
    }
  }

  return new Promise(resolve => {
    fetch(url, newOptions)
      .then(checkStatus)
      .then(response => {
        resolve(response);
      })
      .catch(e => {
        const { response, status } = e;
        if (response) {
          const errortext = codeMessage[status] || response.statusText;
          notification.error({
            message: `请求错误 ${status}: ${response.url}`,
            description: errortext,
          });
        } else {
          notification.error({
            message: `网络连接错误`,
          });
        }
      });
  });
}

export function postForm(url, param) {
  const formData = Object.keys(param).reduce((form, key) => {
    form.append(key, param[key]);
    return form;
  }, new FormData());
  const option = {
    method: 'POST',
    body: formData,
  };
  return request(url, option);
}
